const http = require("http");
const path = require("path");
const fse = require("fs-extra");
var url = require("url");
const multiparty = require("multiparty");

const server = http.createServer();
const UPLOAD_DIR = path.resolve(__dirname, ".", `cutFile`); // 切片存储目录

// 接收请求的参数
const resolvePost = req => {
    return new Promise(res => {
        let chunk = ''
        req.on('data', data => {
            chunk += data
        })
        req.on('end', () => {
            res(JSON.parse(chunk))
        })
    })
}

const pipeStream = (path, writeStream) => {
    // console.log('path', path)
    // if (!fse.existsSync(path)) {
    //     console.log('chunk不存在pipe')
    // }else{
    //     console.log('chunk存在pipe')
    // }
    return new Promise(resolve => {
        const readStream = fse.createReadStream(path);
        readStream.on("end", (err) => {
            fse.unlinkSync(path);
            if (err) {
                console.log(err);
            }
            resolve();
        });
        readStream.pipe(writeStream);
    });
}

// 合并切片
const mergeFileChunk = async (filePath, fileName) => {
    console.log('合并到：', filePath);
    if (fse.existsSync(filePath)) {
        console.log('文件存在，先删除');
        fse.unlinkSync(filePath);
    }
    // filePath：你将切片合并到哪里，的路径
    const chunkDir = path.resolve(UPLOAD_DIR, `${fileName}-chunks`);
    let chunkPaths = null
    // 获取切片文件夹里所有切片，返回一个数组
    chunkPaths = await fse.readdir(chunkDir);
    // console.log({ chunkPaths })
    if (!chunkPaths || chunkPaths.length == 0) {
        return console.log('chunk不存在');
    }
    // 根据切片下标进行排序
    // 否则直接读取目录的获得的顺序可能会错乱
    chunkPaths.sort((a, b) => parseInt(a) - parseInt(b));
    // console.log({ chunkPaths })

    let tmp = path.resolve(chunkDir, chunkPaths[0]);
    let info = fse.statSync(tmp);
    let chunkSize = info.size;
    const arr = chunkPaths.map((chunkPath, index) => {
        return pipeStream(
            path.resolve(chunkDir, chunkPath),
            // 指定位置创建可写流
            fse.createWriteStream(filePath, {
                start: index * chunkSize
            })
        )
    })
    await Promise.all(arr);
    setTimeout(function(){
        fse.rmdirSync(chunkDir); // 合并后删除保存切片的目录
    },1300);
}


server.on("request", async (req, res) => {
    let msg = 'ok';
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Headers", "*");
    res.json = (d) => {
        res.end(JSON.stringify(d));
    }
    if (req.method === "OPTIONS") {
        res.status = 200;
        res.end();
        return;
    }

    if (req.url === '/upload') {
        const multipart = new multiparty.Form();

        multipart.parse(req, async (err, fields, files) => {
            if (err) {
                console.log('errrrr', err)
                return;
            }
            const [file] = files.file;
            // console.log(fields);
            const fileName = fields.fileName[0];
            const chunkIndex = parseInt(fields.chunkIndex[0]);
            const chunkCount = parseInt(fields.chunkCount[0]);
            // 保存切片的文件夹的路径，比如  张远-嘉宾.flac-chunks
            const chunkDir = path.resolve(UPLOAD_DIR, `${fileName}-chunks`);
            // // 切片目录不存在，创建切片目录
            if (!fse.existsSync(chunkDir)) {
                await fse.mkdirs(chunkDir);
            }
            if (!fse.existsSync(file.path)) {
                console.log('chunk不存在');
                msg = 'chunk不存在';
                return res.json({ msg });
            }
            if (!fse.existsSync(`${chunkDir}/${chunkIndex}`)) {
                await fse.move(file.path, `${chunkDir}/${chunkIndex}`); // 把切片移动到切片文件夹
            }
            if (chunkIndex >= (chunkCount - 1)) {
                //merge
                console.log('文件合并');
                msg = 'merge';
                let filePath = path.resolve(UPLOAD_DIR, './', fileName);
                await mergeFileChunk(filePath, fileName);
            }
            res.json({ msg });
        });
    } else {
        let u = req.url;
        let arr = u.split('/');
        if (arr[arr.length - 1] == '') {
            u += 'index.html';
            arr.push('index.html');
        }
        var pathName = path.normalize(url.parse(u).pathname);
        let htmlDir = path.resolve(__dirname, './html/');
        var fullPath = path.resolve(htmlDir, ...arr);
        console.log({ fullPath, pathName, UPLOAD_DIR });
        // res.json({ fullPath, pathName, UPLOAD_DIR });
        if (!fse.existsSync(fullPath)) {
            return res.json({ msg: '404' });
        }
        res.end(fse.readFileSync(fullPath, { encoding: "utf-8" }));
    }
})

server.listen(3000, () => console.log("正在监听 3000 端口"));